/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package msgserver;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.*;
/**
 *
 * @author Данила
 */
public class RMIServer extends UnicastRemoteObject
implements RecieveMessageInterface
{
    public int      thisPort;
    public String   thisAddress;
    Registry registry;    
    HashMap<String, String> clients = new HashMap<String, String>();
    List onlineClients = new ArrayList<String>();
    HashMap<String, String> messages = new HashMap<String, String>();
 
    public RMIServer() throws RemoteException
    {
        try{
            // get the address of this host.
            thisAddress= (InetAddress.getLocalHost()).toString();
        }
        catch(Exception e){
            throw new RemoteException("can't get inet address.");
        }
        thisPort=3232;
        System.out.println("this address="+thisAddress+",port="+thisPort);
        try{
        // create the registry and bind the name and object.
        registry = LocateRegistry.createRegistry( thisPort );
            registry.rebind("rmiServer", this);
        }
        catch(RemoteException e){
        throw e;
        }
    }
    
    @Override
     public void receiveMessage(String username, String message) throws RemoteException {
        messages.put(username, message);
    }
    
     

    @Override
    public void receiveClientData(String username, String password) throws RemoteException {
        clients.put(username, password);
        onlineClients.add(username);
    }

    @Override
    public boolean checkClientData(String username, String password) throws RemoteException {
        if(clients.containsKey(username)) {
            if(clients.get(username).equals(password)) {
                onlineClients.add(username);
                return true;
            } else {
                throw new UnsupportedOperationException("Wrong username or password!");
            }
        } else {
            throw new UnsupportedOperationException("Wrong username or password!");
        }
    }

    @Override
    public int disconnectClient(String username) throws RemoteException {
        onlineClients.remove(username);
        return javax.swing.WindowConstants.EXIT_ON_CLOSE;
    }

    @Override
    public String sendMessage(String username) throws RemoteException {
        String msg = messages.get(username);
        messages.remove(username);
        return msg;
    }

    @Override
    public void hasClientUnrecievedMessage(String username) throws RemoteException {
        if(messages.containsKey(username)) 
            sendMessage(username);
    }

    @Override
    public List getListOnlineClients() throws RemoteException {
        return onlineClients;
    }

    @Override
    public void getFileFromClient(byte[] file) throws RemoteException {
        File tmpFile = new File(FileUtils.getUserDirectory().getAbsolutePath() + File.separator + UUID.randomUUID().toString());
        try {
            tmpFile.createNewFile();
            FileUtils.writeByteArrayToFile(tmpFile, file);
        } catch (IOException ex) {
            Logger.getLogger(RMIServer.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }

    @Override
    public String runProgram(String command) throws RemoteException {
       String result = "";
       try {
            String line;
            Process p = Runtime.getRuntime().exec(command);
            BufferedReader bri = new BufferedReader
              (new InputStreamReader(p.getInputStream()));
            BufferedReader bre = new BufferedReader
              (new InputStreamReader(p.getErrorStream()));
            while ((line = bri.readLine()) != null) {
                result += line;
                System.out.println(line);
            }
            bri.close();
            while ((line = bre.readLine()) != null) {
              System.out.println(line);
            }
            bre.close();
            p.waitFor();
            System.out.println("Done.");
            }
        catch (Exception err) {
            err.printStackTrace();
       }
        return result;
    }

}
